/*
 *
 *    ┏┓　　　┏┓
 *  ┏┛┻━━━┛┻┓
 *  ┃　　　　　　　┃
 *  ┃　　　━　　　┃
 *  ┃　＞　　　＜　┃
 *  ┃　　　　　　　┃
 *  ┃...　⌒　...　┃
 *  ┃　　　　　　　┃
 *  ┗━┓　　　┏━┛
 *      ┃　　　┃
 *      ┃　　　┃
 *      ┃　　　┃
 *      ┃　　　┃  神兽保佑
 *      ┃　　　┃  代码无bug
 *      ┃　　　┃
 *      ┃　　　┗━━━┓
 *      ┃　　　　　　　┣┓
 *      ┃　　　　　　　┏┛
 *      ┗┓┓┏━┳┓┏┛
 *        ┃┫┫　┃┫┫
 *        ┗┻┛　┗┻┛
 *
 * @Descripttion: 路由权限控制模块，token校验，处理路由导航、权限验证和页面加载状态
 * @version: 1.0.0
 * @Date: 2021-04-20 11:06:21
 * @Author: jekingxu@163.com
 * @LastEditTime: 2022-09-27 16:35:06
 * @HomePage: https://xuxiaowen.space/vue3-element-admin
 * @Github: https://github.com/xuxiaowengjt
 */

// 导入必要的依赖和模块
import { ElLoading } from 'element-plus'          // Element Plus 的加载组件
import router from '@/router'                     // Vue Router 实例
import { TOKEN } from './pinia/modules/app'       // TOKEN 常量
import { nextTick } from 'vue'                    // Vue 的 nextTick 方法
import { useApp } from './pinia/modules/app'      // 应用状态管理
import { useAccount } from './pinia/modules/account' // 账户状态管理
import { useMenus } from './pinia/modules/menu'   // 菜单状态管理

/**
 * 生成页面标题
 * @param {string} title - 页面特定标题
 * @returns {string} 完整的页面标题
 */
const getPageTitle = title => {
    const { title: appTitle } = useApp()
    if (title) {
        return `${title} - ${appTitle}`
    }
    return appTitle
}

// 路由白名单，包含无需登录即可访问的路由名称
const WhiteList = ['login', 'lock']

// 全局 loading 实例
let loadingInstance = null

/**
 * 全局前置路由守卫
 * Vue Router 4.x 版本使用 return 代替 next() 进行路由控制
 */
router.beforeEach(async to => {
    // 显示全局加载动画
    loadingInstance = ElLoading.service({
        lock: true,
        background: 'rgba(0, 0, 0, 0.7)',
    })

    // 检查是否是白名单路由
    if (WhiteList.includes(to.name)) {
        return true
    }

    // 检查用户是否已登录（是否存在 token）
    if (!window.localStorage[TOKEN]) {
        // 未登录时重定向到登录页面，并保存目标路由地址
        return {
            name: 'login',
            query: {
                redirect: to.fullPath, // 保存当前路由，登录后可以直接跳转回来
            },
            replace: true,
        }
    } else {
        const { userinfo, getUserinfo } = useAccount()
        // 检查是否已获取用户信息
        if (!userinfo) {
            try {
                // 获取用户信息（包含角色、权限等数据）
                await getUserinfo()
            } catch (err) {
                loadingInstance.close()
                return false
            }
            return to.fullPath
        }

        // 处理动态路由和菜单
        const { menus, generateMenus } = useMenus()
        if (menus.length <= 0) {
            try {
                // 生成动态路由和菜单
                await generateMenus()
                return to.fullPath // 重新触发路由导航以应用新生成的路由
            } catch (err) {
                loadingInstance.close()
                return false
            }
        }

        // 锁屏状态检查
        if (to.name !== 'lock') {
            const { authorization } = useApp()
            if (!!authorization && !!authorization.screenCode) {
                // 如果存在锁屏码，重定向到锁屏页面
                return {
                    name: 'lock',
                    query: {
                        redirect: to.path,
                    },
                    replace: true,
                }
            }
        }
    }
})

/**
 * 全局后置路由守卫
 * 处理页面加载状态和标题更新
 */
router.afterEach(to => {
    // 关闭加载动画
    loadingInstance.close()
    
    // 更新页面标题
    if (router.currentRoute.value.name === to.name) {
        nextTick(() => {
            document.title = getPageTitle(!!to.meta && to.meta.truetitle)
        })
    }
})